﻿#region zh-CHS 2006 - 2007 DemoSoft 团队 | en 2006 - 2007 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the G.O.S.E(Game Online Server Engine) for .NET.
//
//                 2006-2007 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Demo_G.O.S.E.ServerEngine.Map;
using Demo_G.O.S.E.ServerEngine.Util;
using Demo_G.O.S.E.ServerEngine.Item;
using Demo_G.O.S.E.ServerEngine.Timer;
using Demo_G.O.S.E.ServerEngine.Server;
using Demo_G.O.S.E.ServerEngine.Common;
using Demo_G.O.S.E.ServerEngine.Network;
using Demo_G.O.S.E.ServerEngine.Mobile;
using Demo_G.O.S.E.ServerEngine.ThreadPool;
#endregion

namespace Demo_G.O.S.E.ServerEngine.World
{
    /// <summary>
    /// BaseWorld 是管理整个游戏世界的入口
    /// </summary>
    [MultiThreadedSupportgAttribute( "当前的类所有成员都可锁定,支持多线程操作" )]
    public class BaseWorld
    {
        /// <summary>
        /// 
        /// </summary>
        public CallbackThreadPool m_ThreadPool = null;

        /// <summary>
        /// 开始线程池
        /// </summary>
        public void StartThreadPool( int maxThreadsAllowed )
        {
            m_ThreadPool = new CallbackThreadPool( CallbackThreadPool.TIMEOUT_INFINITE, maxThreadsAllowed, maxThreadsAllowed );
            m_ThreadPool.ThreadEvent += new EventHandler<CallbackThreadPoolEventArgs>( ThreadPool_ThreadEvent );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="eventArgs"></param>
        public void ThreadPool_ThreadEvent( object sender, CallbackThreadPoolEventArgs eventArgs )
        {
            switch ( eventArgs.Reason )
            {
                case CallbackReason.AddingThreadToPool:

                    // 向服务程序注册有新的线程在内部运行
                    BaseServer.BeginRegisterThread();

                    break;
                case CallbackReason.RemovingThreadFromPool:

                    // 向服务程序注册创建的新线程已结束
                    BaseServer.EndRegisterThread();
                    break;
                default:

                    break;
            }
        }

        /// <summary>
        /// 停止线程池
        /// </summary>
        public void StopThreadPool()
        {
            m_ThreadPool.Dispose();
        }

        /// <summary>
        /// 表示线程池线程要执行的回调方法。
        /// </summary>
        /// <param name="state"></param>
        public void SliceWorld( object state )
        {
            if ( BaseServer.Closing )
                return;
        }

        #region zh-CHS 私有常量 | en Private Constants
        /// <summary>
        /// 间隔的次数
        /// </summary>
        private const int SAMPLE_INTERVAL = 100;
        /// <summary>
        /// 100秒时间的间隔数值
        /// </summary>
        private const float TICKS_PER_SECOND = TimeSpan.TicksPerSecond * SAMPLE_INTERVAL;
        #endregion

        #region zh-CHS 内部属性 | en Internal Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 游戏世界的线程组
        /// </summary>
        private Thread[] m_WorldThread = new Thread[0];
        #endregion
        /// <summary>
        /// 游戏世界的线程组
        /// </summary>
        internal Thread[] WorldThread
        {
            get { return m_WorldThread; }
            set { m_WorldThread = value; }
        }
        #endregion

        #region zh-CHS 共有属性 | en Public Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 是否正在存储数据中...
        /// </summary>
        private bool m_Saving = false;
        #endregion
        /// <summary>
        /// 是否正在存储数据中...
        /// </summary>
        public bool Saving
        {
            get { return m_Saving; }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 数据存储的时间间隔
        /// </summary>
        private TimeSpan m_SaveTimeSpan = TimeSpan.FromMinutes( 5.0 );
        #endregion
        /// <summary>
        /// 存储数据的时间间隔
        /// </summary>
        public TimeSpan IntervalSave
        {
            get { return m_SaveTimeSpan; }
            set
            {
                if ( m_SaveTimeSpan.Ticks != value.Ticks )
                {
                    m_SaveTimeSpan = value;
                    StartSaveTimeSlice();
                }
            }
        }

        /// <summary>
        /// 给出脚本里面的可运动物体的数量(NPCs、Monster)
        /// </summary>
        public int MobileCount
        {
            get { return m_MobileArray.Length; }
        }

        /// <summary>
        /// 给出脚本里面的道具的数量
        /// </summary>
        public int ItemCount
        {
            get { return m_ItemArray.Length; }
        }

        /// <summary>
        /// 给出脚本里面的地图的数量
        /// </summary>
        public int MapCount
        {
            get { return m_MapArray.Length; }
        }
        #endregion

        #region zh-CHS 共有静态属性 | en Public Static Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 当断开处理的累计数量到该数量时将中断后面的调用
        /// </summary>
        private static long s_BreakCount = 100; // 默认值(在多线程中不因该太多)
        #endregion
        /// <summary>
        /// 当断开处理的累计数量到该数量时将中断后面的调用 中断的数量,减少处理的时间
        /// </summary>
        public static long DisposedBreakCount
        {
            get { return s_BreakCount; }
            set { s_BreakCount = value; }
        }
        #endregion

        #region zh-CHS 内部保护方法 | en Protected Internal Methods
        /// <summary>
        /// 初始化世界服务
        /// </summary>
        protected internal void OnInitOnce()
        {
            // 在开始运行世界之前,初始化一次BaseWorld
            if ( EventInitOnceWorld != null )
            {
                BaseWorldEventArgs l_EventArgs = new BaseWorldEventArgs( this );
                EventInitOnceWorld( l_EventArgs );
            }
        }

        /// <summary>
        /// 结束世界服务
        /// </summary>
        protected internal void OnExit()
        {
            // 在结束世界之前,调用一次
            if ( EventExitWorld != null )
            {
                BaseWorldEventArgs l_EventArgs = new BaseWorldEventArgs( this );
                EventExitWorld( l_EventArgs );
            }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private object m_LockSave = new object();
        #endregion
        /// <summary>
        /// 保存世界服务
        /// </summary>
        protected internal void OnSave()
        {
            if ( Monitor.TryEnter( m_LockSave ) == false )
            {
                LOGs.WriteLine( LogMessageType.MSG_NOTICE, "游戏世界: 游戏世界数据正在保存中,请稍候再试......" );
                return;
            }
            else
            {
                // 保存数据
                if ( EventSaveWorld != null )
                {
                    // 保存数据中......
                    m_Saving = true;

                    LOGs.WriteLine( LogMessageType.MSG_NOTICE, "游戏世界: 开始保存游戏世界数据中......" );

                    BaseWorldEventArgs l_EventArgs = new BaseWorldEventArgs( this );
                    EventSaveWorld( l_EventArgs );

                    LOGs.WriteLine( LogMessageType.MSG_NOTICE, "游戏世界: 游戏世界数据保存完毕." );

                    // 保存数据结束......
                    m_Saving = false;
                }
            }
            Monitor.Exit( m_LockSave );
        }

        /// <summary>
        /// 世界服务开始读取数据
        /// </summary>
        protected internal void OnLoad()
        {
            // 读取需要的一些数据
            if ( EventLoadWorld != null )
            {
                BaseWorldEventArgs l_EventArgs = new BaseWorldEventArgs( this );
                EventLoadWorld( l_EventArgs );
            }
        }

        /// <summary>
        /// 广播数据到整个世界服务
        /// </summary>
        /// <param name="state"></param>
        /// <param name="strText"></param>
        protected internal void OnBroadcast( object state, string strText )
        {
            // 广播数据
            if ( EventBroadcast != null )
            {
                BroadcastEventArgs l_EventArgs = new BroadcastEventArgs( this, strText, state );
                EventBroadcast( l_EventArgs );
            }
        }
        #endregion

        #region zh-CHS 内部方法 | en Internal Method
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 数据保存的时间片
        /// </summary>
        private TimeSlice m_SaveTimeSlice = null;
        #endregion
        /// <summary>
        /// 开始运行数据保存的时间片
        /// </summary>
        internal void StartSaveTimeSlice()
        {
            if ( m_SaveTimeSlice != null )
                m_SaveTimeSlice.IntervalTime = m_SaveTimeSpan;
            else
                // 启动BaseWorld保存数据的时间片
                m_SaveTimeSlice = TimeSlice.DelayCall( m_SaveTimeSpan, m_SaveTimeSpan, new TimeSliceCallback( OnSave ) );
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 循环周期的计数
        /// </summary>
        private int m_CycleIndex = 0;
        /// <summary>
        /// 计算100次循环周期的调用时间率
        /// </summary>
        private float[] m_CyclesPerSecond = new float[SAMPLE_INTERVAL];
        #endregion
        /// <summary>
        /// 开始运行世界服务
        /// </summary>
        internal void RunWorld()
        {
            // 向服务程序注册有新的线程在内部运行
            BaseServer.BeginRegisterThread();

            try
            {
                ulong l_SampleIndex = 0;
                DateTime l_DateTimeNow  = DateTime.Now;
                DateTime l_DateTimeLast = DateTime.Now;
                BaseWorldEventArgs l_EventArgs = new BaseWorldEventArgs( this );

                while ( BaseServer.Closing == false )
                {
                    m_WorldSignal.WaitOne();

                    if ( BaseServer.Closing )
                        break;

                    BaseMobile.ProcessDeltaQueue();
                    BaseItem.ProcessDeltaQueue();

                    TimeSlice.Slice();

                    // 需要保存一个引用的副本,防止多线程添加的时候调用失败的可能
                    // MessagePump[] l_MessagePumpArray = m_MessagePump;
                    // 其实不需要的,数组永远都不会添加和删除

                    // foreach的平均花费时间只有for的30%
                    foreach ( MessagePump messagePump in m_MessagePump )
                        messagePump.Slice();
                    
                    FlushAll();

                    ProcessDisposed();

                    if ( EventSlice != null )
                        EventSlice( l_EventArgs );

                    // 100 次调用计算一次使用的时间率
                    if ( ( ++l_SampleIndex % SAMPLE_INTERVAL ) == 0 )
                    {
                        Interlocked.Increment( ref m_CycleIndex );

                        l_DateTimeNow = DateTime.Now;
                        m_CyclesPerSecond[m_CycleIndex % m_CyclesPerSecond.Length] = TICKS_PER_SECOND / ( l_DateTimeNow.Ticks - l_DateTimeLast.Ticks ); // 计算的时间比率
                        l_DateTimeLast = l_DateTimeNow;
                    }
                }
            }
            catch ( Exception exception )
            {
                BaseServer.UnhandledException( this, new UnhandledExceptionEventArgs( exception, true ) );
            }

            // 向服务程序注册创建的新线程已结束
            BaseServer.EndRegisterThread();
        }

        #region zh-CHS CheckAllAlive(检查客户端状态) 函数 | en CheckAllAlive Methods

        /// <summary>
        /// 初始化在线状态的检查
        /// </summary>
        internal void StartCheckAllAliveTime()
        {
            // 检测用户是否超时
            // 创建检测用户是否超时的时间片(默认5分钟)
            TimeSlice.DelayCall( NetState.CheckAliveTime, NetState.CheckAliveTime, new TimeSliceCallback( CheckAllAlive ) );
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 是否在调用CheckAllAlive(...)中...(防止多线程多次调用CheckAllAlive(...)函数)
        /// </summary>
        private bool m_InCheckAllAlive = false;
        /// <summary>
        /// 是否在调用CheckAllAlive(...)中...的锁
        /// </summary>
        private object m_LockInCheckAllAlive = new object();
        #endregion
        /// <summary>
        /// 检查全部的连接是否有效
        /// </summary>
        private void CheckAllAlive()
        {
            bool l_bIsChange = false;

            // 检查是否已经在处理CheckAllAlive(...)的调用
            if ( Monitor.TryEnter( m_LockInCheckAllAlive ) == false )
                return;
            {
                if ( m_InCheckAllAlive == false ) // 没有锁定
                    l_bIsChange = m_InCheckAllAlive = true;
            }
            Monitor.Exit( m_LockInCheckAllAlive );

            // 已经在处理CheckAllAlive(...)中
            if ( l_bIsChange == false && m_InCheckAllAlive )
                return;

            // 处理数据
            NetState[] netStateArray = NetStateToArray();
            foreach ( NetState netState in netStateArray )
                netState.CheckAlive();

            // 已经处理完CheckAllAlive(...)的调用
            Monitor.Enter( m_LockInCheckAllAlive );
            {
                m_InCheckAllAlive = false;
            }
            Monitor.Exit( m_LockInCheckAllAlive );
        }

        #endregion

        #region zh-CHS FlushAll 函数 | en FlushAll Methods

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 需要处理发送的客户端的集合
        /// </summary>
        private List<NetState> m_NetStateFlush = new List<NetState>();
        /// <summary>
        /// 处理发送的客户端的集合锁
        /// </summary>
        private object m_LockNetStateFlush = new object();
        #endregion
        /// <summary>
        /// 放入处理发送的客户端的集合内,等待处理
        /// </summary>
        /// <param name="netSatate"></param>
        internal void FlushNetStates( NetState netSatate )
        {
            if ( netSatate.IsInFlushQueue() )
                return;
            else
                netSatate.InFlushQueue();

            Monitor.Enter( m_LockNetStateFlush );
            {
                m_NetStateFlush.Add( netSatate );
            }
            Monitor.Exit( m_LockNetStateFlush );
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 是否在调用CheckAllAlive(...)中...(防止多线程多次调用CheckAllAlive(...)函数)
        /// </summary>
        private bool m_InFlushAll = false;
        /// <summary>
        /// 是否在调用CheckAllAlive(...)中...的锁
        /// </summary>
        private object m_LockInFlushAll = new object();
        #endregion
        /// <summary>
        /// 发送全部的数据
        /// </summary>
        internal void FlushAll()
        {
            bool l_bIsChange = false;

            // 检查是否已经在处理FlushAll(...)的调用
            if ( Monitor.TryEnter( m_LockInFlushAll ) == false )
                return;
            {
                if ( m_InFlushAll == false ) // 没有锁定
                    l_bIsChange = m_InFlushAll = true;
            }
            Monitor.Exit( m_LockInFlushAll );

            // 已经在处理FlushAll(...)中
            if ( l_bIsChange == false && m_InFlushAll )
                return;

            // 处理数据
            NetState[] netStateArray = null;

            Monitor.Enter( m_LockNetStateFlush );
            {
                if ( m_NetStateFlush.Count > 0 )
                {
                    netStateArray = m_NetStateFlush.ToArray();
                    m_NetStateFlush.Clear();
                }
            }
            Monitor.Exit( m_LockNetStateFlush );

            if ( netStateArray == null )
                return;

            foreach ( NetState netState in netStateArray )
            {
                if ( netState.Running )
                {
                    netState.Flush();
                    netState.OutFlushQueue();

                    // 如果还有没有全部Flush的数据则添加(再次Flush数据),防止多线程漏处理的问题
                    if ( netState.SendQueue.IsFlushReady )
                        FlushNetStates( netState );
                }
            }

            // 已经处理完FlushAll(...)的调用
            Monitor.Enter( m_LockInFlushAll );
            {
                m_InFlushAll = false;
            }
            Monitor.Exit( m_LockInFlushAll );
        }

        #endregion

        #region zh-CHS ProcessDisposed 方法 | en ProcessDisposed Methods

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 需要处理的无效客户端的集合
        /// </summary>
        private Queue<NetState> m_NetStateDisposed = new Queue<NetState>();
        /// <summary>
        /// 无效客户端的集合锁
        /// </summary>
        private object m_LockNetStateDisposed = new object();
        #endregion
        /// <summary>
        /// 放入无效客户端的集合内,等待处理
        /// </summary>
        /// <param name="netSatate"></param>
        internal void DisposedNetStates( NetState netSatate )
        {
            Monitor.Enter( m_LockNetStateDisposed );
            {
                m_NetStateDisposed.Enqueue( netSatate );
            }
            Monitor.Exit( m_LockNetStateDisposed );
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 是否在调用ProcessDisposed(...)中...(防止多线程多次调用ProcessDisposed(...)函数)
        /// </summary>
        private bool m_InProcessDisposed = false;
        /// <summary>
        /// 是否在调用ProcessDisposed(...)中...的锁
        /// </summary>
        private object m_LockInProcessDisposed = new object();
        #endregion
        /// <summary>
        /// 处理全部的已断开连接的客户,不要处理过多的断开,以影响时间片的处理
        /// </summary>
        internal void ProcessDisposed()
        {
            bool l_bIsChange = false;

            // 检查是否已经在处理ProcessDisposed(...)的调用
            if ( Monitor.TryEnter( m_LockInProcessDisposed ) == false )
                return;
            {
                if ( m_InProcessDisposed == false ) // 没有锁定
                    l_bIsChange = m_InProcessDisposed = true;
            }
            Monitor.Exit( m_LockInProcessDisposed );

            // 已经在处理ProcessDisposed(...)中
            if ( l_bIsChange == false && m_InProcessDisposed )
                return;

            do
            {
                // 使用数组减少锁定时间
                NetState[] netStateArray = null;

                if ( Monitor.TryEnter( m_LockNetStateDisposed ) == false )
                    break;
                {
                    if ( m_NetStateDisposed.Count > 0 )
                    {
                        // 断开连接的客户先进先出列队集合的数量(和中断处理比较)
                        long l_QueueCountAtNetState = m_NetStateDisposed.Count;
                        if ( l_QueueCountAtNetState <= BaseWorld.DisposedBreakCount )
                        {
                            netStateArray = m_NetStateDisposed.ToArray();
                            m_NetStateDisposed.Clear();
                        }
                        else
                        {
                            netStateArray = new NetState[BaseWorld.DisposedBreakCount];
                            for ( long iIndex = 0; iIndex < BaseWorld.DisposedBreakCount; iIndex++ )
                                netStateArray[iIndex] = m_NetStateDisposed.Dequeue();
                        }
                    }
                }
                Monitor.Exit( m_LockNetStateDisposed );

                // 如果没有需要处理的数据则返回
                if ( netStateArray == null )
                    break;

                foreach ( NetState netState in netStateArray )
                {
                    RemoveNetState( netState );
                    netState.Release();
                }
            } while ( false );

            // 已经处理完ProcessDisposed(...)的调用
            Monitor.Enter( m_LockInProcessDisposed );
            {
                m_InProcessDisposed = false;
            }
            Monitor.Exit( m_LockInProcessDisposed );
        }

        #endregion

        #endregion

        #region zh-CHS 共有方法 | en Public Method
        /// <summary>
        /// 广播数据信息
        /// </summary>
        /// <param name="state"></param>
        /// <param name="strText"></param>
        public void Broadcast( object state, string strText )
        {
            OnBroadcast( state, strText );
        }

        /// <summary>
        /// 广播数据信息
        /// </summary>
        /// <param name="state"></param>
        /// <param name="strFormat"></param>
        /// <param name="args"></param>
        public void Broadcast( object state, string strFormat, params object[] args )
        {
            Broadcast( state, string.Format( strFormat, args ) );
        }

        /// <summary>
        /// 保存世界的数据
        /// </summary>
        public void Save()
        {
            // 保存世界的数据必须要成功才返回
            Monitor.Enter( m_LockSave );
            {
                // 保存数据中......
                m_Saving = true;

                LOGs.WriteLine( LogMessageType.MSG_NOTICE, "游戏世界: 开始保存游戏世界数据中......" );

                // 保存数据
                if ( EventSaveWorld != null )
                {
                    BaseWorldEventArgs l_EventArgs = new BaseWorldEventArgs( this );
                    EventSaveWorld( l_EventArgs );
                }

                LOGs.WriteLine( LogMessageType.MSG_NOTICE, "游戏世界: 游戏世界数据保存完毕." );

                // 保存数据结束......
                m_Saving = false;
            }
            Monitor.Exit( m_LockSave );
        }
        #endregion

        #region zh-CHS 共有通知信号方法 | en Public WorldSignal Method
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 游戏世界的通知事件
        /// </summary>
        private static AutoResetEvent m_WorldSignal = new AutoResetEvent( true );
        #endregion
        /// <summary>
        /// 游戏世界的通知信号
        /// </summary>
        public void SetWorldSignal()
        {
            m_WorldSignal.Set();
            m_ThreadPool.QueueUserWorkItem( SliceWorld );
        }
        #endregion

        #region zh-CHS 共有事件 | en Public Event
        /// <summary>
        /// World可处理的时间片
        /// </summary>
        public event SliceEventHandler EventSlice;
        /// <summary>
        /// 
        /// </summary>
        public event InitOnceWorldEventHandler EventInitOnceWorld;
        /// <summary>
        /// 
        /// </summary>
        public event ExitWorldEventHandler EventExitWorld;
        /// <summary>
        /// 
        /// </summary>
        public event LoadWorldEventHandler EventLoadWorld;
        /// <summary>
        /// 
        /// </summary>
        public event SaveWorldEventHandler EventSaveWorld;
        /// <summary>
        /// 
        /// </summary>
        public event BroadcastEventHandler EventBroadcast;
        #endregion

        #region zh-CHS MessagePump 方法 | en MessagePump Method

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 多个监听的端口
        /// </summary>
        private MessagePump[] m_MessagePump = new MessagePump[0];
        #endregion
        /// <summary>
        /// 监听的端口
        /// </summary>
        public MessagePump[] MessagePump
        {
            get { return m_MessagePump; }
        }

        #region zh-CHS MessagePump 方法 | en MessagePump Method
        /// <summary>
        /// 添加监听的端口
        /// </summary>
        /// <param name="messagePump"></param>
        public void AddMessagePump( MessagePump messagePump )
        {
            // 创建新的MessagePump数组,添加数据,交换数组数据,不需要锁定,没有引用时自动会回收数据
            MessagePump[] tempMessagePump = new MessagePump[m_MessagePump.Length + 1];

            for ( int iIndex = 0; iIndex < m_MessagePump.Length; ++iIndex )
                tempMessagePump[iIndex] = m_MessagePump[iIndex];

            tempMessagePump[m_MessagePump.Length] = messagePump;
            messagePump.SetBaseWorld( this );

            m_MessagePump = tempMessagePump;
        }
        #endregion

        #endregion

        #region zh-CHS BaseMap 方法 | en BaseMap Method

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 地图的集合
        /// </summary>
        private Dictionary<long, BaseMap> m_BaseMaps = new Dictionary<long, BaseMap>( 10 );
        /// <summary>
        /// 地图的集合锁
        /// </summary>
        private object m_LockBaseMaps = new object();
        #endregion
        /// <summary>
        /// 添加地图到集合
        /// </summary>
        public void AddMap( Serial iMapID, BaseMap baseMap )
        {
            Monitor.Enter( m_LockBaseMaps );
            {
                m_BaseMaps.Add( iMapID, baseMap );

                m_bIsMapsChange = true;
            }
            Monitor.Exit( m_LockBaseMaps );
        }

        /// <summary>
        /// 在地图的集合内给出某地图
        /// </summary>
        /// <param name="iMapID"></param>
        /// <returns></returns>
        public BaseMap GetMap( Serial iMapID )
        {
            BaseMap l_BaseMap = BaseMap.NullMap;

            Monitor.Enter( m_LockBaseMaps );
            {
                m_BaseMaps.TryGetValue( iMapID, out l_BaseMap );
            }
            Monitor.Exit( m_LockBaseMaps );

            return l_BaseMap;
        }

        /// <summary>
        /// 在地图的集合内删除某地图
        /// </summary>
        /// <param name="iMapID"></param>
        public void RemoveMap( Serial iMapID )
        {
            Monitor.Enter( m_LockBaseMaps );
            {
                m_BaseMaps.Remove( iMapID );

                m_bIsMapsChange = true;
            }
            Monitor.Exit( m_LockBaseMaps );
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 全部地图
        /// </summary>
        private BaseMap[] m_MapArray = new BaseMap[0];
        /// <summary>
        /// 地图的集合数据是否已经改变过
        /// </summary>
        private bool m_bIsMapsChange = true;
        #endregion
        /// <summary>
        /// 全部地图的数组
        /// </summary>
        /// <returns></returns>
        [MultiThreadedWarningAttribute( "(地图)当前的数组是列表临时产生的,不能保存数组用于以后操作:警告!" )]
        public BaseMap[] MapToArray()
        {
            Monitor.Enter( m_LockBaseMaps );
            {
                if ( m_bIsMapsChange )
                {
                    m_MapArray = new BaseMap[m_BaseMaps.Count];

                    int iIndex = 0;
                    foreach ( KeyValuePair<long, BaseMap> itemBaseMap in m_BaseMaps )
                    {
                        m_MapArray[iIndex] = itemBaseMap.Value;
                        ++iIndex;
                    }

                    m_bIsMapsChange = false;
                }
            }
            Monitor.Exit( m_LockBaseMaps );

            return m_MapArray;
        }
        #endregion

        #region zh-CHS NetState 方法 | en BaseItem Method

        #region zh-CHS 内部方法 | en Internal Methods
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 网络客户端的集合
        /// </summary>
        private Dictionary<NetState, NetState> m_NetStates = new Dictionary<NetState, NetState>( 100 );
        /// <summary>
        /// 网络客户端的集合锁
        /// </summary>
        private object m_LockNetStates = new object();
        #endregion
        /// <summary>
        /// 添加客户端到集合
        /// </summary>
        internal void AddNetState( NetState netState )
        {
            Monitor.Enter( m_LockNetStates );
            {
                m_NetStates.Add( netState, netState );

                m_bIsNetStateChange = true;
            }
            Monitor.Exit( m_LockNetStates );
        }

        /// <summary>
        /// 在客户端的集合内删除某客户端
        /// </summary>
        /// <param name="iMapID"></param>
        internal void RemoveNetState( NetState netState )
        {
            Monitor.Enter( m_LockNetStates );
            {
                m_NetStates.Remove( netState );

                m_bIsNetStateChange = true;
            }
            Monitor.Exit( m_LockNetStates );
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 全部网络客户端
        /// </summary>
        private NetState[] m_NetStateArray = new NetState[0];
        /// <summary>
        /// 网络客户端的集合数据是否已经改变过
        /// </summary>
        private bool m_bIsNetStateChange = true;
        #endregion
        /// <summary>
        /// 全部网络客户端的数组
        /// </summary>
        /// <returns></returns>
        [MultiThreadedWarningAttribute( "(NetState)当前的数组是列表临时产生的,不能保存数组用于以后操作(给出部分的实例已经可能无效,请用 Running == true 检查实例是否有效):警告!" )]
        public NetState[] NetStateToArray()
        {
            Monitor.Enter( m_LockNetStates );
            {
                if ( m_bIsNetStateChange )
                {
                    m_NetStateArray = new NetState[m_NetStates.Count];

                    int iIndex = 0;
                    foreach ( KeyValuePair<NetState, NetState> itemNetState in m_NetStates )
                    {
                        m_NetStateArray[iIndex] = itemNetState.Value;
                        ++iIndex;
                    }

                    m_bIsNetStateChange = false;
                }
            }
            Monitor.Exit( m_LockNetStates );

            return m_NetStateArray;
        }
        #endregion

        #endregion

        #region zh-CHS BaseItem 方法 | en BaseItem Method

        #region zh-CHS 内部方法 | en Internal Methods
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 道具的集合
        /// </summary>
        private Dictionary<long, BaseItem> m_BaseItems = new Dictionary<long, BaseItem>( 100 );
        /// <summary>
        /// 道具的集合锁
        /// </summary>
        private object m_LockBaseItems = new object();
        #endregion
        /// <summary>
        /// 添加道具到集合
        /// </summary>
        internal void AddItem( Serial iItemID, BaseItem baseItem )
        {
            Monitor.Enter( m_LockBaseItems );
            {
                m_BaseItems.Add( iItemID, baseItem );

                m_bIsItemsChange = true;
            }
            Monitor.Exit( m_LockBaseItems );
        }

        /// <summary>
        /// 在道具的集合内删除某道具
        /// </summary>
        /// <param name="iMapID"></param>
        internal void RemoveItem( Serial iItemID )
        {
            Monitor.Enter( m_LockBaseItems );
            {
                m_BaseItems.Remove( iItemID );

                m_bIsItemsChange = true;
            }
            Monitor.Exit( m_LockBaseItems );

        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 在道具的集合内给出某道具
        /// </summary>
        /// <param name="iMapID"></param>
        /// <returns></returns>
        public BaseItem GetItem( Serial iItemID )
        {
            BaseItem l_BaseItem = null;

            Monitor.Enter( m_LockBaseItems );
            {
                m_BaseItems.TryGetValue( iItemID, out l_BaseItem );
            }
            Monitor.Exit( m_LockBaseItems );

            return l_BaseItem;
        }


        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 全部道具
        /// </summary>
        private BaseItem[] m_ItemArray = new BaseItem[0];
        /// <summary>
        /// 道具的集合数据是否已经改变过
        /// </summary>
        private bool m_bIsItemsChange = true;
        #endregion
        /// <summary>
        /// 全部道具的数组
        /// </summary>
        /// <returns></returns>
        [MultiThreadedWarningAttribute( "(道具)当前的数组是列表临时产生的,不能保存数组用于以后操作:警告!" )]
        public BaseItem[] ItemToArray()
        {
            Monitor.Enter( m_LockBaseItems );
            {
                if ( m_bIsItemsChange )
                {
                    m_ItemArray = new BaseItem[m_BaseItems.Count];

                    int iIndex = 0;
                    foreach ( KeyValuePair<long, BaseItem> itemBaseItem in m_BaseItems )
                    {
                        m_ItemArray[iIndex] = itemBaseItem.Value;
                        ++iIndex;
                    }

                    m_bIsItemsChange = false;
                }
            }
            Monitor.Exit( m_LockBaseItems );
            
            return m_ItemArray;
        }
        #endregion

        #endregion

        #region zh-CHS BaseItem Type(模型) 方法 | en BaseItem Type Method

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 道具类型的集合
        /// </summary>
        private Dictionary<Type, BaseItem> m_TypeBaseItems = new Dictionary<Type, BaseItem>( 100 );
        /// <summary>
        /// 道具类型的集合锁
        /// </summary>
        private object m_LockTypeBaseItems = new object();
        #endregion
        /// <summary>
        /// 添加道具类型到集合
        /// </summary>
        public void AddTypeItem( Type itemType, BaseItem baseItem )
        {
            Monitor.Enter( m_LockTypeBaseItems );
            {
                m_TypeBaseItems.Add( itemType, baseItem );

                m_bIsTypeItemsChange = true;
            }
            Monitor.Exit( m_LockTypeBaseItems );
        }

        /// <summary>
        /// 在道具类型的集合内给出某道具类型
        /// </summary>
        /// <param name="iMapID"></param>
        /// <returns></returns>
        public BaseItem GetTypeItem( Type itemType )
        {
            BaseItem l_BaseItem = null;

            Monitor.Enter( m_LockTypeBaseItems );
            {
                m_TypeBaseItems.TryGetValue( itemType, out l_BaseItem );
            }
            Monitor.Exit( m_LockTypeBaseItems );

            return l_BaseItem;
        }

        /// <summary>
        /// 在道具类型的集合内删除某道具类型
        /// </summary>
        /// <param name="iMapID"></param>
        public void RemoveTypeItem( Type itemType )
        {
            Monitor.Enter( m_LockTypeBaseItems );
            {
                m_TypeBaseItems.Remove( itemType );

                m_bIsTypeItemsChange = true;
            }
            Monitor.Exit( m_LockTypeBaseItems );
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 全部道具类型
        /// </summary>
        private BaseItem[] m_TypeItemArray = new BaseItem[0];
        /// <summary>
        /// 道具类型的集合数据是否已经改变过
        /// </summary>
        private bool m_bIsTypeItemsChange = true;
        #endregion
        /// <summary>
        /// 全部道具类型的数组
        /// </summary>
        /// <returns></returns>
        [MultiThreadedWarningAttribute( "(道具类型)当前的数组是列表临时产生的,不能保存数组用于以后操作:警告!" )]
        public BaseItem[] TypeItemToArray()
        {
            Monitor.Enter( m_LockTypeBaseItems );
            {
                if ( m_bIsTypeItemsChange )
                {
                    m_TypeItemArray = new BaseItem[m_TypeBaseItems.Count];

                    int iIndex = 0;
                    foreach ( KeyValuePair<Type, BaseItem> itemBaseItem in m_TypeBaseItems )
                    {
                        m_TypeItemArray[iIndex] = itemBaseItem.Value;
                        ++iIndex;
                    }

                    m_bIsTypeItemsChange = false;
                }
            }
            Monitor.Exit( m_LockTypeBaseItems );

            return m_TypeItemArray;
        }

        #endregion

        #region zh-CHS BaseMobile 方法 | en BaseMobile Method

        #region zh-CHS 内部方法 | en Internal Methods
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 移动物体(npc, player, monster)的集合
        /// </summary>
        private Dictionary<long, BaseMobile> m_BaseMobiles = new Dictionary<long, BaseMobile>( 100 );
        /// <summary>
        /// 移动物体(npc, player, monster)的集合锁
        /// </summary>
        private object m_LockBaseMobiles = new object();
        #endregion
        /// <summary>
        /// 添加移动物体(npc, player, monster)到集合
        /// </summary>
        internal void AddMobile( Serial iMobileID, BaseMobile baseMobile )
        {
            Monitor.Enter( m_LockBaseMobiles );
            {
                m_BaseMobiles.Add( iMobileID, baseMobile );

                m_bIsMobilesChange = true;
            }
            Monitor.Exit( m_LockBaseMobiles );
        }

        /// <summary>
        /// 在移动物体(npc, player, monster)的集合内删除某移动物体(npc, player, monster)
        /// </summary>
        /// <param name="iMapID"></param>
        internal void RemoveMobile( Serial iMobileID )
        {
            Monitor.Enter( m_LockBaseMobiles );
            {
                m_BaseMobiles.Remove( iMobileID );

                m_bIsMobilesChange = true;
            }
            Monitor.Exit( m_LockBaseMobiles );
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 在移动物体(npc, player, monster)的集合内给出某移动物体(npc, player, monster)
        /// </summary>
        /// <param name="iMapID"></param>
        /// <returns></returns>
        public BaseMobile GetMobile( Serial iMobileID )
        {
            BaseMobile l_BaseMobile = null;

            Monitor.Enter( m_LockBaseMobiles );
            {
                m_BaseMobiles.TryGetValue( iMobileID, out l_BaseMobile );
            }
            Monitor.Exit( m_LockBaseMobiles );

            return l_BaseMobile;
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 全部移动物体(npc, player, monster)
        /// </summary>
        private BaseMobile[] m_MobileArray = new BaseMobile[0];
        /// <summary>
        /// 移动物体(npc, player, monster)的集合数据是否已经改变过
        /// </summary>
        private bool m_bIsMobilesChange = true;
        #endregion
        /// <summary>
        /// 全部移动物体(npc, player, monster)的数组
        /// </summary>
        /// <returns></returns>
        [MultiThreadedWarningAttribute( "(移动物-npc,player,monster)当前的数组是列表临时产生的,不能保存数组用于以后操作:警告!" )]
        public BaseMobile[] MobileToArray()
        {
            Monitor.Enter( m_LockBaseMobiles );
            {
                if ( m_bIsMobilesChange )
                {
                    m_MobileArray = new BaseMobile[m_BaseMobiles.Count];

                    int iIndex = 0;
                    foreach ( KeyValuePair<long, BaseMobile> itemBaseMobile in m_BaseMobiles )
                    {
                        m_MobileArray[iIndex] = itemBaseMobile.Value;
                        ++iIndex;
                    }

                    m_bIsMobilesChange = false;
                }
            }
            Monitor.Exit( m_LockBaseMobiles );

            return m_MobileArray;
        }
        #endregion

        #endregion

        #region zh-CHS BaseMobile Type(模型) 方法 | en BaseMobile Type Method

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 移动物体类型(npc, player, monster)的集合
        /// </summary>
        private Dictionary<Type, BaseMobile> m_TypeBaseMobiles = new Dictionary<Type, BaseMobile>( 100 );
        /// <summary>
        /// 移动物体类型(npc, player, monster)的集合锁
        /// </summary>
        private object m_LockTypeBaseMobiles = new object();
        #endregion
        /// <summary>
        /// 添加移动物体类型(npc, player, monster)到集合
        /// </summary>
        public void AddTypeMobile( Type mobileType, BaseMobile baseMobile )
        {
            Monitor.Enter( m_LockTypeBaseMobiles );
            {
                m_TypeBaseMobiles.Add( mobileType, baseMobile );

                m_bIsTypeMobilesChange = true;
            }
            Monitor.Exit( m_LockTypeBaseMobiles );
        }

        /// <summary>
        /// 在移动物体类型(npc, player, monster)的集合内给出某移动物体(npc, player, monster)
        /// </summary>
        /// <param name="iMapID"></param>
        /// <returns></returns>
        public BaseMobile GetTypeMobile( Type mobileType )
        {
            BaseMobile l_BaseMobile = null;

            Monitor.Enter( m_LockTypeBaseMobiles );
            {
                m_TypeBaseMobiles.TryGetValue( mobileType, out l_BaseMobile );
            }
            Monitor.Exit( m_LockTypeBaseMobiles );

            return l_BaseMobile;
        }

        /// <summary>
        /// 在移动物体类型(npc, player, monster)的集合内删除某移动物体(npc, player, monster)
        /// </summary>
        /// <param name="iMapID"></param>
        public void RemoveTypeMobile( Type mobileType )
        {
            if ( mobileType == null )
                return;

            Monitor.Enter( m_LockTypeBaseMobiles );
            {
                m_TypeBaseMobiles.Remove( mobileType );

                m_bIsTypeMobilesChange = true;
            }
            Monitor.Exit( m_LockTypeBaseMobiles );
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 全部移动物体类型(npc, player, monster)
        /// </summary>
        private BaseMobile[] m_TypeMobileArray = new BaseMobile[0];
        /// <summary>
        /// 移动物体类型(npc, player, monster)的集合数据是否已经改变过
        /// </summary>
        private bool m_bIsTypeMobilesChange = true;
        #endregion
        /// <summary>
        /// 全部移动物体类型(npc, player, monster)的数组
        /// </summary>
        /// <returns></returns>
        [MultiThreadedWarningAttribute( "(移动物类型-npc,player,monster)当前的数组是列表临时产生的,不能保存数组用于以后操作:警告!" )]
        public BaseMobile[] TypeMobileToArray()
        {
            Monitor.Enter( m_LockTypeBaseMobiles );
            {
                if ( m_bIsTypeMobilesChange )
                {
                    m_TypeMobileArray = new BaseMobile[m_TypeBaseMobiles.Count];

                    int iIndex = 0;
                    foreach ( KeyValuePair<Type, BaseMobile> itemBaseMobile in m_TypeBaseMobiles )
                    {
                        m_TypeMobileArray[iIndex] = itemBaseMobile.Value;
                        ++iIndex;
                    }

                    m_bIsTypeMobilesChange = false;
                }
            }
            Monitor.Exit( m_LockTypeBaseMobiles );

            return m_TypeMobileArray;
        }
        #endregion
    }
}
#endregion